<script>
	/*
	需求:请手写实现一个call函数
	面试题:请说明call和apply的区别
		相同点:
				1.都可以修改被借调函数本次执行的this指向
				2.都会同步调用被借调函数
				3.都会将被借调函数的执行结果作为返回值进行返回
				4.如果传入的第一个参数不是对象数据类型,会做出对应效果
						-如果是undefined或者null
								本轮this就是window
						-如果是number,boolean,string类型的基础数据
								本轮this就是对应的包装类对象
		不同点:
				1.传入实参的个数不相同
						call接收的实参数量  0->无限大
								会将第一个实参作为this指向使用
								会将第二个开始的实参作为参数传递给被借调函数

						apply接收的实参数量 0->2
								会将第一个实参作为this指向使用
								会将第二个实参作为参数传递给被借调函数
										第二个实参必须是数组(如果想要传递多个数据给被借调函数,就在该数组中书写)
	        */

	// 使用es6手写call
	function a(x, y, z) {
		console.log(this, x, y, z);
		return x + y + z;
	}

	var obj = {
		name: "我是obj",
	};

	Function.prototype.myCall = function (thatThis) {
		var result;
		if (thatThis == null) {
			thatThis = window;
		}
		// 更加完善的call方法
		//     if(thatThis===undefined||thatThis===null){
		//         thatThis = window;
		//     }else if(type==='number'){
		//         thatThis = new Number(thatThis);
		//     }else if(type==='string'){
		//         thatThis = new String(thatThis);
		//     }else if(type==='boolean'){
		//         thatThis = new Boolean(thatThis);
		//     }

		// 收集接收的参数
		var arr = [];
		for (var i = 1; i < arguments.length; i++) {
			arr.push(arguments[i]);
		}

		thatThis._fn = this;
		// result = thatThis._fn(arr.toString());
		// 转换目标： thatThis._fn(1,2,3...);
		result = eval("thatThis._fn(" + arr.toString() + ")");
		delete thatThis._fn;
		return result;
	};

	var res = a.myCall(obj, 1, 2, 3);
	console.log(res);
</script>
